package mpbe.estructura.secciones.hormigon_armado.graficos;

/*
 * Este codigo es software libre y se encuentra licenciado 
 * bajo los términos de la Licencia Pública General de GNU versión 3 
 * según se encuentra publicada por la Free Software Foundation.
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Autor: Martin Pablo Bellanca <martin.bellanca@gmail.com>
 * web: http://mpbe.blogspot.com/
 */

import java.util.Vector;

import org.GNOME.Accessibility.Application;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Drawable;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;

import com.sun.xml.internal.bind.v2.schemagen.xmlschema.Appinfo;

import mpbe.MPBE;
import mpbe.estructura.Unidad;
import mpbe.estructura.UnidadesLista;
import mpbe.estructura.secciones.hormigon_armado.Barra_Redonda;
import mpbe.estructura.secciones.hormigon_armado.Hormigon_armado;
import mpbe.estructura.secciones.hormigon_armado.SHGrupo_de_Barras;
import mpbe.estructura.secciones.hormigon_armado.contornos.SHContorno;
import mpbe.geometria.Limites;
import mpbe.geometria.Poligono;
import mpbe.geometria.Punto;

/**
 * @author mpbe
 *
 */
public class SHDibSeccion {
	public DibSeccionDibujar DIBUJAR = null;
	public DibSeccionColores COLORES = null;
	
	//Seccion
	private Hormigon_armado seccion = null;
	private Limites limitesVSeccion= null;
	private Limites limitesHSeccion = null; 
	
	private double escalaX = 0; //escala del dibujo
	private double escalaY = 0; 
	private int corrimientoX; //distancia ejes globales a ejes locales de la seccion 
	private int corrimientoY;
	private Unidad ucm = null;
	
	// diametros
	private int diamNodos;
	private double diamBarras;
	
	// varias
	private double decRedondeo;
	
	// Internas
	private Display display = null; //pasar como variable externa en el constructorsi no se puede obtener
	private Rectangle area = null;
	//private Drawable img = null;
	private GC gc = null;
	
	//************************************
	// Constructores
	//************************************
	public SHDibSeccion(Display display) {
		//Objetos a dibujar por defecto
		DIBUJAR = new DibSeccionDibujar();
		// colores por defecto
		COLORES = new DibSeccionColores();

		// diametros por defecto
		diamNodos = 8;
		diamBarras = 8;
		
		this.display = display;
		
		UnidadesLista ul = new UnidadesLista("archivo");
		ucm = ul.getLongitud("cm");
		
	}
	public SHDibSeccion(Display display, GC gc) {
		//Objetos a dibujar por defecto
		DIBUJAR = new DibSeccionDibujar();
		// colores por defecto
		COLORES = new DibSeccionColores();

		// diametros por defecto
		diamNodos = 8;
		diamBarras = 8;
		
		this.display = display;
		//this.img = img;
		this.gc = gc;
		
		UnidadesLista ul = new UnidadesLista("archivo");
		ucm = ul.getLongitud("cm");
	}
	
	
	//------------------------------------------------------------
	// Funciones de Dibujo de la Seccion
	//------------------------------------------------------------
	public boolean dibujar_Seccion (double escalaX, double escalaY, int corrimientoX, int corrimientoY, Rectangle area){
		decRedondeo = seccion.getGenerales().uLongitud.Coef*100;
		this.corrimientoX = corrimientoX;
		this.corrimientoY = corrimientoY;
		this.escalaX = escalaX;
		this.escalaY = escalaY;
		this.area = area;
		
		limitesVSeccion = seccion.contornos.getLimitesV();
		limitesHSeccion = seccion.contornos.getLimitesH();
		
		if (DIBUJAR.isDibEjes()) dibEjes();
		if (DIBUJAR.isDibNodos()) dibNodos();
		if (DIBUJAR.isDibContornos()) dibContorno();
		if (DIBUJAR.isDibBarras()) dibBarras(true);
		if (DIBUJAR.isDibBarras_a_Esc()) dibBarras(true);
		if (DIBUJAR.isDibTXTNodos()||DIBUJAR.isDibTXTCoord()) dibTXTNodos();
		if (DIBUJAR.isDibEjeN()) SHDibujar.dibEjeNeutro(gc, corrimientoX, corrimientoY, escalaY, area, display.getSystemColor(COLORES.getcolorEjeNeutro()), seccion);
		if (DIBUJAR.isDibCotas()) dibCotas();
		if (DIBUJAR.isDibEstribos()) dibEstrivo();
		return false;
	}

	
	private void dibEjes(){
		int dx = area.x;
		int dy = area.y;
		
		// define el color
		gc.setForeground(display.getSystemColor(COLORES.getColorEjes())); 
		gc.setBackground(display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
		// define el ancho
		gc.setLineWidth(1);
		// define tipo de linea
		gc.setLineStyle(SWT.LINE_DASHDOT);
		// dibuja Ejes X
		gc.drawLine(dx+5, dy+SHDibujar.transformar(0, corrimientoY, escalaY), dx+(int)(area.width-5), dy+SHDibujar.transformar(0, corrimientoY, escalaY));
		gc.drawText("X", dx+(int)(area.width-13), dy+SHDibujar.transformar(0, corrimientoY, escalaY)-20);
		// Dibuja Ejes Y
		gc.drawLine(dx+SHDibujar.transformar(0, corrimientoX, escalaX), dy+5, dx+SHDibujar.transformar(0, corrimientoX, escalaX), dy+(int)(area.height-5));
		gc.drawText("Y", dx+SHDibujar.transformar(0, corrimientoX, escalaX)+8, dy+0);
		
	}
	private void dibNodos(){
		int dx = area.x;
		int dy = area.y;
		
		// define el color
		gc.setForeground(display.getSystemColor(COLORES.getColorNodos())); 
		gc.setBackground(display.getSystemColor(COLORES.getColorNodos()));
		// define el ancho
		gc.setLineWidth(1);
		// define tipo de linea
		gc.setLineStyle(SWT.LINE_CUSTOM);
		// dibuja los nodos
		int canc = seccion.contornos.size();
		int cann = 0;
		SHContorno co = new SHContorno();
		for (int c=0; c<canc; c++){
			co = seccion.contornos.get(c);
			if (co.activo) {
				cann = co.nodos.size();
				Punto p = new Punto();
				for (int n=0; n<cann; n++){
					p = co.nodos.get(n);
					gc.fillOval(dx+SHDibujar.transformar(p.X, corrimientoX, escalaX)-diamNodos/2, dy+SHDibujar.transformar(p.Y, corrimientoY, escalaY)-diamNodos/2, diamNodos, diamNodos);
				}
			}
		}
	}
	private void dibTXTNodos(){
		int dx = area.x;
		int dy = area.y;
		
		//Define la letra
		Font font = new Font(display,"Arial",8,SWT.NONE);
		gc.setFont(font);
		
		// define el color 
		gc.setBackground(display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
		// define el ancho
		gc.setLineWidth(1);
		// define tipo de linea
		gc.setLineStyle(SWT.LINE_CUSTOM);
		// dibuja los nodos
		int canc = seccion.contornos.size();
		int cann = 0;
		SHContorno co = new SHContorno();
		for (int c=0; c<canc; c++){
			co = seccion.contornos.get(c);
			if (co.activo) {
				cann = co.nodos.size();
				Punto p = new Punto();
				Punto pa = new Punto(); // nodo anterior
				Punto pp = new Punto(); // nodo posterior
				Punto va = new Punto(); // vector anterior
				Punto vp = new Punto(); // vector posterior
				int [] cuadrantes = {0,0,0,0};
				int cud = 0, PX = 0, PY = 0, PCX=0, PCY=0;
				for (int n=0; n<cann; n++){
					for (int cc=0; cc<4; cc++) cuadrantes[cc]=0;
					cud = 0; PX = 0; PY = 0;
					// Carga nodos actual, anterior y posterior
					if (n==0) pa = co.nodos.get(cann-1); else pa = co.nodos.get(n-1); 
					if (n==cann-1) pp = co.nodos.get(0); else pp = co.nodos.get(n+1);
					p = co.nodos.get(n);
					// Calcula los vectores con cero en p
					va.X = pa.X - p.X;
					va.Y = pa.Y - p.Y;
					vp.X = pp.X - p.X;
					vp.Y = pp.Y - p.Y;
					// marca cuadrantes 
					marcar_cuadrantes(cuadrantes, va);
					marcar_cuadrantes(cuadrantes, vp);
					//Obtiene el ancho de los cuadros de texto
					Point tamTXTNod = gc.stringExtent(""+n);
					String txtCoord = "("+MPBE.redondear(p.X, decRedondeo)+","+MPBE.redondear(p.Y, decRedondeo)+")";
					Point tamTXTCoord = gc.stringExtent(txtCoord);
					// define ubicacion del texto en funcion del cuadrante
					for (int cc=0; cc<4; cc++){
						if (cuadrantes[cc]==0) 
							cud += Math.pow(2, cc);
						else if (cuadrantes[cc]==2) {
							cc += 2;
							if (cc>3) cc-=4;
							cud = (int) Math.pow(2, cc);
							break;
						}
					}
					switch (cud) {
						case 1: // cuadrante 0 (sup-izq)
							PX = SHDibujar.transformar(p.X, corrimientoX, escalaX)-10-diamNodos;
							PY = SHDibujar.transformar(p.Y, corrimientoY, escalaY)-10-diamNodos;
							PCX = -tamTXTCoord.x/2;
							PCY = -tamTXTCoord.y;
							break;
						case 2: // cuadrante 1 (sup-der)
							PX = SHDibujar.transformar(p.X, corrimientoX, escalaX)+diamNodos;
							PY = SHDibujar.transformar(p.Y, corrimientoY, escalaY)-10-diamNodos;
							PCX = -tamTXTCoord.x/2;
							PCY = -tamTXTCoord.y;
							break;
						case 4: // cuadrante 2 (inf-der)
							PX = SHDibujar.transformar(p.X, corrimientoX, escalaX)+diamNodos;
							PY = SHDibujar.transformar(p.Y, corrimientoY, escalaY)+diamNodos;
							PCX = -tamTXTCoord.x/2;
							PCY = tamTXTCoord.y;
							break;
						case 8: // cuadrante 3 (inf-izq)
							PX = SHDibujar.transformar(p.X, corrimientoX, escalaX)-10-diamNodos;
							PY = SHDibujar.transformar(p.Y, corrimientoY, escalaY)+diamNodos;
							PCX = -tamTXTCoord.x/2;
							PCY = tamTXTCoord.y;
							break;
						case 3: // cuadrantes 0 y 1
							PX = SHDibujar.transformar(p.X, corrimientoX, escalaX)-10;
							PY = SHDibujar.transformar(p.Y, corrimientoY, escalaY)-15-diamNodos;
							PCX = -tamTXTCoord.x/2;
							PCY = -tamTXTCoord.y;
							break;
						case 6: // cuadrantes 1 y 2
							PX = SHDibujar.transformar(p.X, corrimientoX, escalaX)+diamNodos;
							PY = SHDibujar.transformar(p.Y, corrimientoY, escalaY)-10;
							PCX = -tamTXTCoord.x/2;
							PCY = tamTXTCoord.y;
							break;
						case 12: // cuadrantes 2 y 3
							PX = SHDibujar.transformar(p.X, corrimientoX, escalaX)-5;
							PY = SHDibujar.transformar(p.Y, corrimientoY, escalaY)+5;
							break;
						case 9: // cuadrantes 3 y 0
							PX = SHDibujar.transformar(p.X, corrimientoX, escalaX)-20;
							PY = SHDibujar.transformar(p.Y, corrimientoY, escalaY)-10;
							PCX = -tamTXTCoord.x/2;
							PCY = tamTXTCoord.y;
							break;
						case 5: // cuadrantes 0 y 2
							if (p.X>=0) {
								PX = SHDibujar.transformar(p.X, corrimientoX, escalaX)+diamNodos;
								PY = SHDibujar.transformar(p.Y, corrimientoY, escalaY)+diamNodos;
								PCX = -tamTXTCoord.x/2;
								PCY = -tamTXTCoord.y;
							} else {
								PX = SHDibujar.transformar(p.X, corrimientoX, escalaX)-10-diamNodos;
								PY = SHDibujar.transformar(p.Y, corrimientoY, escalaY)-10-diamNodos;
								PCX = -tamTXTCoord.x/2;
								PCY = tamTXTCoord.y;
							}
							break;
						case 10: // cuadrantes 1 y 3
							if (p.X>=0) {
								PX = SHDibujar.transformar(p.X, corrimientoX, escalaX)+diamNodos;
								PY = SHDibujar.transformar(p.Y, corrimientoY, escalaY)-10-diamNodos;
								PCX = -tamTXTCoord.x/2;
								PCY = -tamTXTCoord.y;
							} else {
								PX = SHDibujar.transformar(p.X, corrimientoX, escalaX)-10-diamNodos;
								PY = SHDibujar.transformar(p.Y, corrimientoY, escalaY)+diamNodos;
								PCX = -tamTXTCoord.x/2;
								PCY = tamTXTCoord.y;
							}
					} 	
					PX +=dx;
					PY +=dy;
					if (DIBUJAR.isDibTXTNodos()){
						gc.setForeground(display.getSystemColor(COLORES.getColorTXTNodos()));
						gc.drawText(""+n, PX, PY, true);	
					}
					if (DIBUJAR.isDibTXTCoord()){
						gc.setForeground(display.getSystemColor(COLORES.getColorTXTCoord()));
						p = co.nodos.get(n);
						//gc.drawText("("+p.X+","+p.Y+")", PX-po.x/2, PY+po.y, true);
						gc.drawText(txtCoord, PX+PCX, PY+PCY, true);
					}
				}
			}
		}
	}
	private void marcar_cuadrantes(int [] cuadrantes, Punto vector){
		if (vector.Y==0) { //vector sobre eje X
			if (vector.X>0){
				cuadrantes[1]+=1;
				cuadrantes[2]+=1;
			}
			else if (vector.X<0) {
				cuadrantes[0]+=1;
				cuadrantes[3]+=1;
			}
		}
		else if (vector.X==0){ // vector sobre eje Y
			if (vector.Y>0){ 
				cuadrantes[0]+=1;
				cuadrantes[1]+=1;
			}
			else if (vector.Y<0) {
				cuadrantes[2]+=1;
				cuadrantes[3]+=1;
			}
		} else if (vector.X>0){ // X positivo
			if (vector.Y>0) cuadrantes[1]+=1;
			else cuadrantes[2]+=1;
		} else { // X negativo
			if (vector.Y>0) cuadrantes[0]+=1;
			else cuadrantes[3]+=1;
		}
	}
	private void dibContorno(){
		int dx = area.x;
		int dy = area.y;
		
		// define el color
		gc.setForeground(display.getSystemColor(COLORES.getColorContornos())); 
		// define el ancho
		gc.setLineWidth(2);
		// define tipo de linea
		gc.setLineStyle(SWT.LINE_CUSTOM);
		// dibuja el contorno
		int canc = seccion.contornos.size();
		int cann = 0;
		SHContorno co = new SHContorno();
		int [] ar;
		for (int c=0; c<canc; c++){
			co = seccion.contornos.get(c);
			if (co.activo) {
				cann = co.nodos.size();
				ar = new int [cann*2];
				Punto p = new Punto();
				for (int n=0; n<cann; n++){
					p = co.nodos.get(n);
					ar[n*2] = dx+(int) SHDibujar.transformar(p.X, corrimientoX, escalaX);
					ar[n*2+1] = dy+(int) SHDibujar.transformar(p.Y, corrimientoY, escalaY);
				}
				gc.drawPolygon(ar);
			}
		}
		
	}
	private void dibBarras(boolean escalarDiametro){
		int dx = area.x;
		int dy = area.y;
		
		// define el ancho
		gc.setLineWidth(1);
		// define tipo de linea
		gc.setLineStyle(SWT.LINE_CUSTOM);
		// dibuja el barras
		int cangr = seccion.grupos.size();
		SHGrupo_de_Barras gb = null;
		Barra_Redonda br = null;
		for (int gg = 0; gg<cangr; gg++){
			gb = seccion.grupos.get(gg);
			if (gb.activo) {
				//	define el color de las barras
				gc.setForeground(display.getSystemColor(COLORES.getColorBarras())); 
				gc.setBackground(display.getSystemColor(COLORES.getColorBarras()));
				for (int bb=0; bb<gb.barras.size(); bb++){
					br = gb.barras.get(bb);
					// dibuja la barra
					//if (secY.min<br.posY)
					if (escalarDiametro) 
						diamBarras = (double)(UnidadesLista.convertir(br.diametro/10, ucm, seccion.getULongitud())*escalaX);
					gc.fillOval(dx+SHDibujar.transformar(br.posX, corrimientoX, escalaX)-(int)(diamBarras/2), dy+SHDibujar.transformar(br.posY, corrimientoY, escalaY)-(int)(diamBarras/2), (int)diamBarras, (int)diamBarras);
					
				}
			}
		}
		
	}
	private void dibCotas(){
		int dx = area.x;
		int dy = area.y;
		
		//	define el color
		gc.setForeground(display.getSystemColor(COLORES.getColorCotasLineas())); 
		gc.setBackground(display.getSystemColor(COLORES.getColorCotasLineas()));
		// define el ancho
		gc.setLineWidth(1);
		// define tipo de linea
		gc.setLineStyle(SWT.LINE_SOLID);
		// Limites de la seccion
		Limites lv = seccion.contornos.getLimitesV();
		Limites lh = seccion.contornos.getLimitesH();
		// vectores para guardar los puntos a acotar
		Vector <Double> cotasX = new Vector<Double>(); 
		Vector <Double> cotasY = new Vector<Double>();
		// carga vectores  en forma ordenada
		int canc = seccion.contornos.size();
		int cann = 0;
		SHContorno co = new SHContorno();
		for (int c=0; c<canc; c++){
			co = seccion.contornos.get(c);
			if (co.activo) {
				cann = co.nodos.size();
				Punto p = new Punto();
				for (int n=0; n<cann; n++){
					p = co.nodos.get(n);
					if (cotasX.size()==0) cotasX.add(p.X);
					else {
						for (int j=0; j<cotasX.size(); j++){
							if (cotasX.get(j)==p.X) break;
							if ((j==0)&&(p.X<cotasX.get(j))) {cotasX.add(0, p.X); break; }
							if ((j==cotasX.size()-1)&&(p.X>cotasX.get(j))) {cotasX.add(p.X); break;}
							if ((p.X>cotasX.get(j))&&(p.X<cotasX.get(j+1))) {cotasX.add(j+1, p.X); break;}	
						}
					}
					if (cotasY.size()==0) cotasY.add(p.Y);
					else {
						for (int j=0; j<cotasY.size(); j++){
							if (cotasY.get(j)==p.Y) break;
							if ((j==0)&&(p.Y<cotasY.get(j))) {cotasY.add(0, p.Y); break;}
							if ((j==cotasY.size()-1)&&(p.Y>cotasY.get(j))) {cotasY.add(p.Y); break;}
							if ((p.Y>cotasY.get(j))&&(p.Y<cotasY.get(j+1))) {cotasY.add(j+1, p.Y); break;}	
						}
					}
				}
			}
		}
		// Dibuja cotas X
		int pos, posa = 0;
		int posY = dy+SHDibujar.transformar(lv.max, corrimientoY, escalaY)-20;
		Point tamanotxt = new Point(0,0);
		double txt;
		gc.drawLine(dx+SHDibujar.transformar(lh.min, corrimientoX, escalaX)-5, posY, dx+SHDibujar.transformar(lh.max, corrimientoX, escalaX)+5, posY);
		for (int p=0; p<cotasX.size(); p++){
			pos = dx+SHDibujar.transformar(cotasX.get(p), corrimientoX, escalaX);
			gc.drawLine(pos, posY-7, pos, posY+7);
			gc.fillOval(pos-2, posY-2, 4, 4);
			if (p!=0){
				txt = MPBE.redondear(cotasX.get(p)-cotasX.get(p-1),decRedondeo);
				tamanotxt = gc.textExtent(""+txt);
				gc.drawText(""+txt,(int)(posa+(pos-posa)/2-(int) (tamanotxt.x/2)) , posY-tamanotxt.y, true);
			}
			posa = pos;
		}
		
		// Dibuja cotas Y
		int posX = dx+SHDibujar.transformar(lh.max, corrimientoX, escalaX)+20;
		gc.drawLine(posX, dy+SHDibujar.transformar(lv.min, corrimientoY, escalaY)+5, posX, dy+SHDibujar.transformar(lv.max, corrimientoY, escalaY)-5);
		for (int p=0; p<cotasY.size(); p++){
			pos = dy+SHDibujar.transformar(cotasY.get(p), corrimientoY, escalaY);
			gc.drawLine(posX-7, pos, posX+7, pos);
			gc.fillOval(posX-2, pos-2, 4, 4);
			if (p!=0){
				txt = MPBE.redondear(cotasY.get(p)-cotasY.get(p-1),decRedondeo);
				tamanotxt = gc.textExtent(""+txt);
				gc.drawText(""+txt, posX+2, (int)(posa+(pos-posa)/2-(int) (tamanotxt.y/2)), true);
			}
			posa = pos;
		}
	}
	//private void dibEstribos
	private void dibEstrivo() {
		double rec = UnidadesLista.convertir(seccion.getGenerales().recubrimiento, ucm, seccion.getULongitud());
		
		//define el color
		gc.setForeground(display.getSystemColor(COLORES.getColorEstribos())); 
		//gc.setBackground(display.getSystemColor(COLORES.getColorCotasLineas()));
		// define el ancho
		gc.setLineWidth(1);
		// define tipo de linea
		gc.setLineStyle(SWT.LINE_SOLID);
		
		// Dibuja el poligono
		double diamEst = UnidadesLista.convertir(seccion.getGenerales().diamEstribos, ucm, seccion.getULongitud());		
		
		// Obtiene el poligono 2
		Poligono contorno = seccion.contornos.get(0).getPolygon1();
		
		Poligono estEx = contorno.offset(rec);
		estEx = estEx.escalar(escalaX, escalaY);
		estEx = estEx.mover(corrimientoX, corrimientoY);
		gc.drawPolygon(estEx.getArray_int());
		
		Poligono estIn = contorno.offset((rec+diamEst));
		estIn = estIn.escalar(escalaX, escalaY);
		estIn = estIn.mover(corrimientoX, corrimientoY);
		gc.drawPolygon(estIn.getArray_int());
		
	}

	
	//-----------------------------------------
	// Getter y setter de diametros
	//-----------------------------------------	
	/**
	 * @return
	 * @uml.property  name="diamBarras"
	 */
	public double getDiamBarras() {
		return diamBarras;
	}
	/**
	 * @param diamBarras
	 * @uml.property  name="diamBarras"
	 */
	public void setDiamBarras(int diamBarras) {
		this.diamBarras = diamBarras;
	}

	/**
	 * @return
	 * @uml.property  name="diamNodos"
	 */
	public int getDiamNodos() {
		return diamNodos;
	}
	/**
	 * @param diamNodos
	 * @uml.property  name="diamNodos"
	 */
	public void setDiamNodos(int diamNodos) {
		this.diamNodos = diamNodos;
	}


	public Hormigon_armado getSeccion() {
		return seccion;
	}
	public void setSeccion(Hormigon_armado seccion) {
		this.seccion = seccion;
	}
	
//	public Drawable getDrawable() {
//		return img;
//	}
//	public void setDrawable(Drawable img) {
//		this.img = img;
//		this.gc = new GC(img);
//	}
	
	public GC getGC() {return gc;}
	public void setGC(GC gc) {this.gc = gc;}
	
}

